package com.tentative.competition.common.utils.file;

import cn.afterturn.easypoi.cache.manager.POICacheManager;
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.word.WordExportUtil;
import cn.hutool.core.util.ObjUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.PictureRenderData;
import com.tentative.competition.common.config.ServerConfig;
import com.tentative.competition.common.config.TentativeCompetitionConfig;
import com.tentative.competition.common.model.resp.WorkMapInfoResp;
import com.tentative.competition.common.model.schedule.vo.FileVo;
import org.apache.http.entity.ContentType;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * @auther: Smile Huang
 * @date: 2023/6/29 21:06
 * @desc:
 * @version: 2.0
 */
@Component
public class WorkUtils {


    @Autowired
    private ServerConfig serverConfig;

    private static final String TEMPLATEPATH = "template/schedule_works.docx";

    /**
     * 依据模板生成work上传文件
     * @return
     */
    public FileVo uploadWork(WorkMapInfoResp infoResps) {
        if (ObjUtil.isEmpty(infoResps)){
            throw new RuntimeException("没有可导出的数据");
        }
        final Map<String, Object> params = new HashMap<>();
        try {
        //简单渲染文本
        params.put("worksName",infoResps.getWorksName());
        params.put("pic",new PictureRenderData(600, 600, infoResps.getWorksImgMainUrl()));
        getImage(params, infoResps.getWorksImgMainUrl());
        params.put("content", infoResps.getContent());
//        params.put("teamName", infoResps.getTeamName());
//        params.put("guidanceName", infoResps.getGuidanceName());
//        params.put("unveilUniversity", infoResps.getUnveilUniversity());
//        params.put("synopsis", infoResps.getSynopsis());
//        params.put("worksOriginality", infoResps.getWorksOriginality());
//        params.put("studyContent", infoResps.getStudyContent());

//        File file = new File(TEMPLATEPATH);
//        String fileName = infoResps.getWorksName();
//        XWPFDocument template = XWPFTemplate.compile(file).render(params);
//        MultipartFile multipartFile = new MockMultipartFile(fileName + ".docx",fileName + ".docx",ContentType.APPLICATION_OCTET_STREAM.toString(), is);
//        String upload = FileUploadUtils.upload(TentativeCompetitionConfig.getUploadPath(),multipartFile);
//        FileOutputStream out = new FileOutputStream(new File(upload));
//        template.write(out);
//        out.flush();
//        out.close();
//        template.close();

        XWPFDocument doc = null;
        doc = WordExportUtil.exportWord07(TEMPLATEPATH, params);
        String fileName = infoResps.getWorksName();
        if (ObjUtil.isNotEmpty(doc)){
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            doc.write(os);
            byte[] b = os.toByteArray();
            InputStream is=new ByteArrayInputStream(b);
            MultipartFile multipartFile = new MockMultipartFile(fileName + ".docx",fileName + ".docx",ContentType.APPLICATION_OCTET_STREAM.toString(), is);
            String upload = FileUploadUtils.upload(TentativeCompetitionConfig.getUploadPath(),multipartFile);
            FileVo vo = new FileVo();
            vo.setFileName(FileUtils.getName(upload));
            vo.setFileUrl(upload);
            return vo;
        }else {
            throw new RuntimeException("获取work模板失败！");
        }
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("work文件生成异常！");
        }
    }

    public static byte[] readByByteArrayOutputStream(String fileFullName) throws IOException {
        File file = new File(fileFullName);
        checkFileExists(file);
        // 传统IO方式
        //1、定义一个Byte字节数组输出流，设置大小为文件大小
        //2、将打开的文件输入流转换为Buffer输入流，循环 读取buffer输入流到buffer[]缓冲，并将buffer缓冲数据输入到目标输出流。
        //3、将目标输出流转换为字节数组。
        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
        BufferedInputStream bin = null;
        try {
            bin = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[1024];
            while (bin.read(buffer) > 0) {
                bos.write(buffer);
            }
            return bos.toByteArray();
        } finally {
            closeInputStream(bin);
            closeOutputStream(bos);
        }
    }

    /**
     * 下载img
     * @param urlImg
     * @return
     * @throws Exception
     */
    public static byte[] getImg(String urlImg)throws Exception{
        //获取人员照片的地址
        URL url = new URL(urlImg);
        //打开链接
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置请求方式为"GET"
        conn.setRequestMethod("GET");
        //超时响应时间为5秒
        conn.setConnectTimeout(5 * 1000);
        //通过输入流获取图片数据
        InputStream inStream = conn.getInputStream();
        //得到图片的二进制数据，以二进制封装得到数据，具有通用性
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度，如果为-1，代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while ((len = inStream.read(buffer)) != -1){
            //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }

    /**
     * 把对应的图片设置到单元格中
     * @param map 单元格数据对象
     * @param urlImg 需要传输的图片
     * @return
     * @throws Exception
     */
    public static Map<String, Object> getImage(Map<String, Object> map ,String urlImg)throws Exception{
        ImageEntity image = new ImageEntity();
        image.setData(readByByteArrayOutputStream(urlImg));
        image.setType(ImageEntity.Data);
        image.setHeight(600);
        image.setWidth(600);
        map.put("pic",image);
        return map;
    }

    private static void checkFileExists(File file) throws FileNotFoundException {
        if (file == null || !file.exists()) {
            System.err.println("file is not null or exist !");
            throw new FileNotFoundException(file.getName());
        }
    }
    private static void closeOutputStream(OutputStream bos) {
        try {
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void closeInputStream(InputStream in) {
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
